# 导入根目录作为模块搜索路径
import os, sys

# ([".."] * 4) 就是项目目录里面 4 层
parent_path = os.path.abspath(os.path.join(__file__, *([".."] * 3)))
sys.path.insert(0, parent_path)

import time

from core.utils.logger import logging


class StateMachine:
    def __init__(self):
        self.__current_state = None
        self.__state_callbacks = {}
        self.__last_transition_time = None
        self.__wait_time = 0

    def set_state_config(self, state, callback):
        self.__state_callbacks[state] = callback

    def set_initial_state(self, initial_state):
        self.__current_state = initial_state
        self.__last_transition_time = time.time()

    def get_current_state(self):
        return self.__current_state

    def run_once(self) -> bool:
        callback = self.__state_callbacks.get(self.__current_state)
        if not callback:
            raise Exception(f"未找到状态 {self.__current_state} 的配置")

        # 检查是否需要等待
        elapsed_time = time.time() - self.__last_transition_time
        if elapsed_time < self.__wait_time:
            return False

        # 执行回调函数
        callback = self.__state_callbacks[self.__current_state]

        # 尝试调用回调
        try:
            new_state, wait_time = callback()
        except TypeError as e:
            logging.exception(
                f"状态 {self.__current_state} 的回调函数未返回新状态或等待时间"
            )
            raise e

        logging.debug(f"从状态 {self.__current_state} 切换到状态 {new_state}")
        self.__current_state = new_state
        self.__wait_time = wait_time
        self.__last_transition_time = time.time()

        return True

    def run(self):
        while self.__current_state in self.__state_callbacks:
            self.run_once()
        logging.warning(f"状态机已结束, 未知状态为 {self.__current_state}")


if __name__ == "__main__":
    from enum import Enum

    class State(Enum):
        STATE_1 = 1
        STATE_2 = 2
        STATE_3 = 3

    # 示例回调函数
    def callback_1():
        logging.info("执行回调函数 1")
        return State.STATE_2, 2

    def callback_2():
        logging.info("执行回调函数 2")
        return State.STATE_1, 3
        return State.STATE_3, 3

    state_machine = StateMachine()
    state_machine.set_state_config(State.STATE_1, callback_1)
    state_machine.set_state_config(State.STATE_2, callback_2)
    state_machine.set_initial_state(State.STATE_1)
    # state_machine.run()

    while True:
        # logging.info(state_machine.run_once())
        state_machine.run_once()
